#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
主应用入口
"""

import logging
import asyncio
from contextlib import asynccontextmanager

from fastapi import FastAPI, HTTPException
from fastapi.middleware.cors import CORSMiddleware
from fastapi.staticfiles import StaticFiles

from app.core.config import settings
from app.core.database import engine, Base
# 导入API路由
from app.api import streams, recordings, monitor, servers, tasks_api, hls_api, transcode_templates, auth, user_management, media_files
from app.services.monitor_service import MonitorService, get_monitor_service
from app.services.media_server import MediaServer, get_media_server
from app.services.ffmpeg_service import get_ffmpeg_service
from app.services.task_queue_manager import start_task_queue, stop_task_queue
from app.services.stream_monitor import get_stream_monitor

import signal
import sys
import os

# 全局变量跟踪是否正在关闭
is_shutting_down = False

def signal_handler(signum, frame):
    """信号处理函数，确保Ctrl+C能完全退出"""
    global is_shutting_down
    
    if is_shutting_down:
        # 如果已经在关闭过程中，强制退出
        logger.info("收到强制退出信号，立即终止...")
        os._exit(0)
    
    is_shutting_down = True
    logger.info("收到关闭信号，开始优雅关闭...")
    
    # 触发FastAPI的关闭
    raise KeyboardInterrupt

# 注册信号处理器
signal.signal(signal.SIGINT, signal_handler)
signal.signal(signal.SIGTERM, signal_handler)

# 配置日志
logging.basicConfig(
    level=getattr(logging, settings.LOG_LEVEL.upper()),
    format='%(asctime)s - %(name)s - %(levelname)s - %(message)s'
)
logger = logging.getLogger(__name__)

# 全局服务实例
# 使用单例模式获取所有服务实例
ffmpeg_service = get_ffmpeg_service()
media_server = get_media_server()
stream_monitor = get_stream_monitor()
monitor_service = get_monitor_service()


@asynccontextmanager
async def lifespan(app: FastAPI):
    """应用生命周期管理"""
    # 启动阶段
    logger.info("流媒体服务启动中...")
    
    # 初始化各个服务
    try: 
        
        logger.info("FFmpeg服务已就绪")        
        # await monitor_service.start()  
        # await stream_monitor.start_monitoring()
        await start_task_queue()
        
    except Exception as e:
        logger.error(f"服务启动失败: {e}")
        raise
    
    yield
    
    # 关闭阶段
    logger.info("关闭应用...")
    
    try:
        # 设置超时时间
        timeout = 10
        
        # 关闭FFmpeg服务
        logger.info("正在停止FFmpeg服务...")
        await asyncio.wait_for(ffmpeg_service.stop_all_processes(), timeout=timeout)
        logger.info("FFmpeg服务已停止")
        
        # 关闭任务队列
        logger.info("正在停止任务队列...")
        await asyncio.wait_for(stop_task_queue(), timeout=timeout)
        logger.info("任务队列已停止")
        
        # 停止实时监控系统
        logger.info("正在停止实时监控系统...")
        await asyncio.wait_for(monitor_service.stop(), timeout=timeout)
        logger.info("实时监控系统已停止")
        
        # 停止流监控服务
        logger.info("正在停止流监控服务...")
        await asyncio.wait_for(stream_monitor.stop_monitoring(), timeout=timeout)
        logger.info("流监控服务已停止")
        
        logger.info("所有服务已安全关闭")
        
    except asyncio.TimeoutError:
        logger.error("关闭超时，强制终止...")
    except Exception as e:
        logger.error(f"关闭过程中出错: {e}")
        # 记录异常但不阻止退出


# 创建FastAPI应用
app = FastAPI(
    title="直播管理系统",
    description="直播流管理和录制系统",
    version="2.0.0",
    lifespan=lifespan,
    redirect_slashes=True
)

# 配置CORS
app.add_middleware(
    CORSMiddleware,
    allow_origins=["*"],
    allow_credentials=True,
    allow_methods=["*"],
    allow_headers=["*"],
)

# 挂载静态文件（注意：媒体服务已经挂载了根路径，这里避免冲突）
# app.mount("/static", StaticFiles(directory="static"), name="static")

# 注册路由
app.include_router(auth.router, prefix="/api/auth", tags=["auth"])
app.include_router(user_management.router, prefix="/api", tags=["users"])
app.include_router(streams.router, prefix="/api", tags=["streams"])
app.include_router(tasks_api.router, prefix="/api/tasks", tags=["tasks"])
app.include_router(recordings.router, prefix="/api/recordings", tags=["recordings"])
app.include_router(monitor.router, prefix="/api/monitor", tags=["monitor"])
app.include_router(servers.router, prefix="/api/servers", tags=["servers"])
app.include_router(transcode_templates.router, prefix="/api/transcode-templates", tags=["transcode-templates"])# 注册媒体文件访问路由
app.include_router(media_files.router)


@app.get("/")
async def root():
    """根路径"""
    return {
        "message": "直播管理系统 API",
        "version": "2.0.0",
        "docs": "/docs",
        "features": {
            "task_queue": "基于MySQL的持久化任务队列",
            "process_pool": "进程池管理",
            "auto_retry": "自动重试机制",
            "crash_recovery": "崩溃恢复"
        },
        "media_endpoints": {
            "recordings": "http://localhost:8187/view/hls/{录制目录名}/index.m3u8",
            "screenshots": "http://localhost:8187/screenshots/{文件名}",
            "api": "/api/media"
        }
    }


@app.get("/health")
async def health_check():
    """健康检查端点"""
    try:
        # 检查流监控状态
        monitor_status = stream_monitor.is_running
        
        # 检查任务服务状态
        task_status = True  # task_service总是可用
        
        # 检查实时监控系统
        monitor_service_status = monitor_service.is_running
        
        # 检查任务队列
        from app.services.task_queue_manager import get_task_queue
        task_queue = get_task_queue()
        scheduler_status = task_queue.running
        
        if monitor_status and task_status and monitor_service_status and scheduler_status:
            return {"status": "healthy", "services": {
                "stream_monitor": "running",
                "task_service": "ready",
                "monitor_service": "running",
                "media_server": "ready",
                "task_scheduler": "running"
            }}
        else:
            return {"status": "unhealthy", "services": {
                "stream_monitor": "running" if monitor_status else "stopped",
                "task_service": "ready" if task_status else "error",
                "monitor_service": "running" if monitor_service_status else "stopped",
                "media_server": "ready",
                "task_scheduler": "running" if scheduler_status else "stopped"
            }}
            
    except Exception as e:
        logger.error(f"健康检查失败: {e}")
        raise HTTPException(status_code=500, detail=str(e))


if __name__ == "__main__":
    import uvicorn
    uvicorn.run(
        "app.main:app",
        host="0.0.0.0",
        port=8187,
        reload=False  # 禁用reload避免事件循环问题
    )